from typing import Callable

from serpentarium import SingleUsePlugin

from common.event_queue import IAgentEventPublisher
from common.types import AgentID
from infection_monkey.exploit import (
    IAgentBinaryRepository,
    IAgentOTPProvider,
    IHTTPAgentBinaryServerRegistrar,
)
from infection_monkey.network import TCPPortSelector
from infection_monkey.propagation_credentials_repository import IPropagationCredentialsRepository

from .i_plugin_factory import IPluginFactory


class ExploiterPluginFactory(IPluginFactory):
    def __init__(
        self,
        agent_id: AgentID,
        http_agent_binary_server_registrar: IHTTPAgentBinaryServerRegistrar,
        agent_binary_repository: IAgentBinaryRepository,
        agent_event_publisher: IAgentEventPublisher,
        propagation_credentials_repository: IPropagationCredentialsRepository,
        tcp_port_selector: TCPPortSelector,
        otp_provider: IAgentOTPProvider,
        create_plugin: Callable[..., SingleUsePlugin],
    ):
        self._agent_id = agent_id
        self._http_agent_binary_server_registrar = http_agent_binary_server_registrar
        self._agent_binary_repository = agent_binary_repository
        self._agent_event_publisher = agent_event_publisher
        self._propagation_credentials_repository = propagation_credentials_repository
        self._tcp_port_selector = tcp_port_selector
        self._otp_provider = otp_provider
        self._create_plugin = create_plugin

    def create(self, plugin_name: str) -> SingleUsePlugin:
        return self._create_plugin(
            plugin_name=plugin_name,
            agent_id=self._agent_id,
            agent_binary_repository=self._agent_binary_repository,
            agent_event_publisher=self._agent_event_publisher,
            propagation_credentials_repository=self._propagation_credentials_repository,
            tcp_port_selector=self._tcp_port_selector,
            otp_provider=self._otp_provider,
            http_agent_binary_server_registrar=self._http_agent_binary_server_registrar,
        )
